package cn._51doit.akka.rpc

import java.util.UUID

import akka.actor.{Actor, ActorSystem, Props}
import com.typesafe.config.ConfigFactory

import scala.concurrent.duration._ //这个包只能手动导入

/**
 * @create: 2021-10-08 19:41
 * @author: 今晚打脑斧
 * @program: Worker
 * @Description:
 *    Worker
 **/
class Worker(val masterHost: String, val masterPort: Int, val workerMemory: Int, val workerCores: Int) extends Actor{

//  val workerId = "w001"
  val workerId = UUID.randomUUID().toString

  //生命周期方法(按照一定顺序执行,并且必须执行)
  //在构造方法之后,receive方法之前,执行一次
  override def preStart(): Unit = {
    //先跟Master建立连接
    val masterRef = context.actorSelection(s"akka.tcp://${Master.MASTER_ACTOR_SYSTEM_NAME}@$masterHost:$masterPort/user/${Master.MASTER_ACTOR_NAME}")
    //向Master发送注册消息（workerId、内存、cpu核数）
    masterRef ! RegisterWorker(workerId, workerMemory, workerCores)
  }

  override def receive: Receive = {
    case RegisteredWorker => {
      //启动一个定时器,定期向Master发送心跳
      import context.dispatcher  //dispatcher 调度员  导入隐式参数
      context.system.scheduler.schedule(0 millisecond,3000 millisecond,sender() , HeartBeat(workerId))
    }
  }
}
object Worker{

  val WORKER_ACTOR_SYSTEM_NAME = "WorkerActorSystem"
  val WORKER_ACTOR_NAME = "WorkerActor"

  def main(args: Array[String]): Unit = {

    val masterHost = args(0)        //master的ip
    val masterPort = args(1).toInt  //master的端口
    val workerHost = args(2)        //worker的ip
    val workerPort = args(3).toInt  //worker的端口
    val workerMemory = args(4).toInt//worker的内存
    val workerCores = args(5).toInt //worker的CPU核数

    val configStr =
      s"""
        |akka.actor.provider = "akka.remote.RemoteActorRefProvider"
        |akka.remote.netty.tcp.hostname = $workerHost
        |akka.remote.netty.tcp.port = $workerPort
        |""".stripMargin;
    val config = ConfigFactory.parseString(configStr)
    val workerActorSystem = ActorSystem(WORKER_ACTOR_SYSTEM_NAME, config)
    workerActorSystem.actorOf(Props(new Worker(masterHost, masterPort, workerMemory, workerCores)), WORKER_ACTOR_NAME);
  }
}